package com.isoftstone.util;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sun.net.ftp.FtpClient;
import sun.net.ftp.FtpDirEntry;

import java.io.*;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class SunFtpUtil {

    private static Logger logger = LoggerFactory.getLogger(SunFtpUtil.class);

    private static SunFtpUtil instance = null;

    public static synchronized SunFtpUtil getSunFtpUtil() {
        if (null == instance) {
            instance = new SunFtpUtil();
        }
        return instance;
    }

    public SunFtpUtil() {
    }

    /**
     * 社银ftp链接及登录
     * @param url ip地址
     * @param port 端口号
     * @param user 用户
     * @param pass 密码
     * @return FtpClient
     **/
    public FtpClient connectFTP(String url, int port, String user, String pass) {
        FtpClient ftpClient = null;
        try {
            SocketAddress socketAddress = new InetSocketAddress(url, port);
            ftpClient = FtpClient.create();
            ftpClient.connect(socketAddress);
            ftpClient.login(user, pass.toCharArray());
            ftpClient.setBinaryType();
//            System.out.println("connect success!");
        } catch (Exception e) {
            e.printStackTrace();
        }

        return ftpClient;
    }

    /**
     * 社银ftp上传文件
     * @param localFile 本地文件路径
     * @param ftpFile ftp文件路径
     * @param ftpClient 连接的ftp
     * @return boolean 判断是否上传成功
     **/
    public boolean upload(String localFile, String ftpFile, FtpClient ftpClient) {
        boolean result = false;
        OutputStream outputStream = null;
        FileInputStream fileInputStream = null;
        try {
            outputStream = ftpClient.putFileStream(ftpFile);
            File file = new File(localFile);
            fileInputStream = new FileInputStream(file);
            byte[] bytes = new byte[1024];
            int c;
            while ((c = fileInputStream.read(bytes)) != -1) {
                outputStream.write(bytes, 0, c);
            }
//            System.out.println("upload success!");
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (outputStream != null) {
                    outputStream.close();
                }
                if (fileInputStream != null) {
                    fileInputStream.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    /**
     * 社银ftp下载文件
     * @param localFile 本地文件路径
     * @param ftpFile ftp文件路径
     * @param ftpClient 连接的ftp
     * @return boolean 判断是否下载成功
     **/
    public boolean download(String localFile, String ftpFile, FtpClient ftpClient) {
        boolean result = false;
        InputStream inputStream = null;
        FileOutputStream fileOutputStream = null;
        try {
            inputStream = ftpClient.getFileStream(ftpFile);
            File file = new File(localFile);
            byte[] bytes = new byte[1024];
            int c;
            fileOutputStream = new FileOutputStream(file);
            while ((c = inputStream.read(bytes)) != -1) {
                fileOutputStream.write(bytes, 0, c);
            }
//            System.out.println("download success!");
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
                if (fileOutputStream != null) {
                    fileOutputStream.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    /**
     * 判断ftp指定银行文件是否存在
     * @param remoteDir ftp文件路径
     * @param wantFileName ftp文件
     * @param ipAddr ip地址
     * @param user 用户
     * @param pass 密码
     * @return boolean 判断文件是否存在
     **/
    public boolean  testFileExist(String remoteDir,  String wantFileName, String ipAddr, String user, String pass) throws Exception {
        boolean result = false;
        //输出信息字符串
        String str;
        //和服务器建立连接
        FtpClient ftp = FtpClient.create(ipAddr); // 根据服务器ip建立连接

        //获得响应信息
        str = ftp.getLastResponseString();
        logger.info("连接服务器:" + str);

        //登陆到Ftp服务器// 根据用户名和密码登录服务器
        ftp.login(user, pass.toCharArray());
//        if(!getServerFileNameList(ftp,remoteDir,wantFileName)) {
//            return false;
//        }

        str = ftp.getLastResponseString();
        logger.info("登录:" + str);

        //打开并定位到服务器目录
        //打开服务器上的文件目录
        str = ftp.getLastResponseString();
        logger.info("打开服务器目录:" + str);
        // 转化为二进制的文件
        ftp.setBinaryType();
        // 找到要读取的文件
        ftp.changeDirectory(remoteDir);
        Iterator<FtpDirEntry> files = ftp.listFiles(remoteDir);
        List<String> list = new ArrayList<String>();
        while (files.hasNext()){
            String name = files.next().toString().substring(0,39);
//            System.out.println(name);
            if(wantFileName.equals(name)){
                result = true;
            }
        }
        return result;

    }

    /**
     * 修改ftp指定银行文件名称
     * @param remoteDir ftp文件路径
     * @param wantFileName ftp文件
     * @param ipAddr ip地址
     * @param user 用户
     * @param pass 密码
     * @return boolean 判断文是否修改成功
     **/
    public boolean  reName(String remoteDir,  String wantFileName, String reName, String ipAddr, String user, String pass) throws Exception {
        boolean result = false;
        //输出信息字符串
        String str;
        //和服务器建立连接
        FtpClient ftp = FtpClient.create(ipAddr); // 根据服务器ip建立连接

        //获得响应信息
        str = ftp.getLastResponseString();
//        logger.info("连接服务器:" + str);

        //登陆到Ftp服务器// 根据用户名和密码登录服务器
        ftp.login(user, pass.toCharArray());
//        if(!getServerFileNameList(ftp,remoteDir,wantFileName)) {
//            return false;
//        }

        str = ftp.getLastResponseString();
//        logger.info("登录:" + str);

        //打开并定位到服务器目录
        //打开服务器上的文件目录
        str = ftp.getLastResponseString();
//        logger.info("打开服务器目录:" + str);
        // 转化为二进制的文件
        ftp.setBinaryType();
        // 找到要读取的文件
        ftp.changeDirectory(remoteDir);
        ftp.rename(wantFileName, reName);
        Iterator<FtpDirEntry> files = ftp.listFiles(remoteDir);
        while (files.hasNext()){
            String s = files.next().toString().substring(0,39);
//            System.out.println(s);
            if(reName.equals(s)){
                result = true;
            }
        }
        return result;

    }

    /**
     * 从ftp服务器下载银行文件
     * @param remoteDir ftp文件路径
     * @param localDir 本地文件存储路径
     * @param wantFileName 文件名称
     * @param ipAddr ip地址
     * @param user 用户
     * @param pass 密码
     * @throws Exception
     * @return boolean 判断是否下载成功
     **/
    public boolean downLoadZipFile(String remoteDir, String localDir, String wantFileName, String ipAddr, String user, String pass) throws Exception {

        //输出信息字符串
        String str;
        //和服务器建立连接
        FtpClient ftp = FtpClient.create(ipAddr); // 根据服务器ip建立连接

        //获得响应信息
        str = ftp.getLastResponseString();
        logger.info("连接服务器:" + str);

        //登陆到Ftp服务器// 根据用户名和密码登录服务器
        ftp.login(user, pass.toCharArray());
//        if(!getServerFileNameList(ftp,remoteDir,wantFileName)) {
//            return false;
//        }

        str = ftp.getLastResponseString();
        logger.info("登录:" + str);

        //打开并定位到服务器目录
        //打开服务器上的文件目录
        str = ftp.getLastResponseString();
        logger.info("打开服务器目录:" + str);
        // 转化为二进制的文件
        ftp.setBinaryType();
        // 找到要读取的文件
        //TelnetInputStream ftpIn = ftp.get(wantFileName + ".zip");
        //TelnetInputStream ftpIn = ftp.getFileStream(wantFileName + ".zip");
        InputStream ftpIn = ftp.getFileStream(remoteDir + wantFileName);
        //TelnetInputStream ftpIn = new TelnetInputStream(xInputStream);

        byte[] buf = new byte[204800];
        int bufsize = 0;
        //File f = new File("c:\\BaseMap");

        String toLocalPath = localDir + wantFileName;
       /*File f=new File(toLocalPath);
       f.mkdirs();*/
        FileOutputStream ftpOut = new FileOutputStream(toLocalPath);
        int readLine = 0;
        while ((bufsize = ftpIn.read(buf, 0, buf.length)) != -1) {
            //System.out.println(bufsize);
            ftpOut.write(buf, 0, bufsize);
            readLine = +bufsize;
        }
//        System.out.println(readLine);
        ftpOut.close();
        ftpIn.close();
        ftp.close();
        logger.info("下载" + wantFileName + ",完成!");

        return true;

    }

    /**
     * 取得ftp服务器上某个目录下的所有文件名
     * @param ftp FtpClient类实例; folderName,服务器的文件夹名
     * @return list 某目录下文件名列表
     * @throws Exception
     **/
    private boolean getServerFileNameList(FtpClient ftp, String folderName, String wantFileName) throws Exception {
        boolean result = false;

        BufferedReader dr = new BufferedReader(new InputStreamReader(ftp.nameList(folderName + wantFileName)));
        String srcName;
        String desName;
        while ((srcName = dr.readLine()) != null) {
            srcName = srcName.replace("/", "");
            desName = (folderName + wantFileName).trim().replace("\\", "");
            if (desName.equals(srcName.trim())) {
                result = true;
                break;
            }
        }
        return result;
    }

    /**
     * 判断本地文件是否存在
     * @param localDir 文件本地路径
     * @param wantFileName 文件名称
     * @return boolean
     **/
    public boolean judeFileExists(String localDir, String wantFileName) {
        boolean result = false;
        File file = new File(localDir + wantFileName);
        if (file.exists()) {
//            System.out.println("file exists");
            result = true;
        } else {
//            System.out.println("file not exists, create it ...");
        }
        return result;
    }

    /**
     * 上传ftp银行文件
     * @param remoteDir ftp文件路径
     * @param localDir 本地文件存储路径
     * @param wantFileName 文件名称
     * @param ipAddr ip地址
     * @param user 用户
     * @param pass 密码
     * @return boolean 判断文件是否上传成功
     * @throws Exception
     **/
    public boolean upLoadZipFile(String remoteDir, String localDir, String wantFileName, String ipAddr, String user, String pass) throws Exception {

        //输出信息字符串
        String str;
        //和服务器建立连接
        FtpClient ftp = FtpClient.create(ipAddr); // 根据服务器ip建立连接

        //获得响应信息
        str = ftp.getLastResponseString();
        logger.info("连接服务器:" + str);

        //登陆到Ftp服务器// 根据用户名和密码登录服务器
        ftp.login(user, pass.toCharArray());

//        if(!getServerFileNameList(ftp,fes_DownLoad,wantFileName)) {
//            return false;
//        }
        if (judeFileExists(localDir, wantFileName)) {

        } else {
            return false;
        }

        str = ftp.getLastResponseString();
        logger.info("登录:" + str);

        //打开并定位到服务器目录
        //打开服务器上的文件目录
        str = ftp.getLastResponseString();
        logger.info("打开服务器目录:" + str);
        // 转化为二进制的文件
        ftp.setBinaryType();
        // 找到要读取的文件

        //TelnetInputStream ftpIn = ftp.get(wantFileName + ".zip");
        //TelnetInputStream ftpIn = ftp.getFileStream(wantFileName + ".zip");
        //InputStream ftpIn = ftp.getFileStream(remoteDir + wantFileName);
        OutputStream ftpOut = ftp.putFileStream(remoteDir + wantFileName);
        //TelnetInputStream ftpIn = new TelnetInputStream(xInputStream);

        byte[] buf = new byte[204800];
        int bufsize = 0;
        //File f = new File("c:\\BaseMap");

        //String toLocalPath = fes_DownLoad + wantFileName;
        String toLocalPath = localDir + wantFileName;
       /*File f=new File(toLocalPath);
       f.mkdirs();*/
        //FileOutputStream ftpOut = new FileOutputStream(toLocalPath);
        FileInputStream ftpIn = new FileInputStream(toLocalPath);
        int readLine = 0;
        while ((bufsize = ftpIn.read(buf, 0, buf.length)) != -1) {
            //System.out.println(bufsize);
            ftpOut.write(buf, 0, bufsize);
            readLine = +bufsize;
        }
        System.out.println(readLine);
        ftpOut.close();
        ftpIn.close();
        ftp.close();
        logger.info("上传" + wantFileName + ",完成!");

        return true;

    }

    /**
     * 判断ftp社银文件
     * @param remoteDir ftp文件路径
     * @param wantFileName 文件名称
     * @param ipAddr ip地址
     * @param port 端口号
     * @param user 用户
     * @param pass 密码
     * @return boolean 判断文件是否存在
     * @throws Exception
     **/
    public boolean testFesFile(String remoteDir, String wantFileName, String ipAddr, int port, String user, String pass) throws Exception {
        boolean result = false;
        FtpClient ftp = null;
        try {
            SocketAddress addr = new InetSocketAddress(ipAddr, port);
            ftp = FtpClient.create();
            ftp.connect(addr);
            ftp.login(user, pass.toCharArray());
            ftp.setBinaryType();
        } catch (Exception e) {
            e.printStackTrace();
        }
//        ftp.changeDirectory(remoteDir);
        Iterator<FtpDirEntry> files = ftp.listFiles(remoteDir);
//        List<String> list = new ArrayList<String>();
        while (files.hasNext()){
            String s = files.next().toString();
            String s1 = s.substring(0,s.indexOf("."))+".dat";
//            System.out.println(s+"==="+s1);
            if(wantFileName.equals(s1)){
                result = true;
            }
        }
        return result;
    }

    /**
     * 获取ftp社银文件MD5
     * @param remoteDir ftp文件路径
     * @param wantFileName 文件名称
     * @param ipAddr ip地址
     * @param port 端口号
     * @param user 用户
     * @param pass 密码
     * @return String 文件MD5
     * @throws Exception
     **/
    public String MD5ZipFile(String remoteDir, String wantFileName, String ipAddr, int port, String user, String pass) throws Exception {
        FtpClient ftp = null;
        try {
            SocketAddress addr = new InetSocketAddress(ipAddr, port);
            ftp = FtpClient.create();
            ftp.connect(addr);
            ftp.login(user, pass.toCharArray());
            ftp.setBinaryType();
        } catch (Exception e) {
            e.printStackTrace();
        }
        InputStream ftpIn = ftp.getFileStream(remoteDir + wantFileName);
        FileInputStream fis = (FileInputStream) ftpIn;
        String md5 = DigestUtils.md5Hex(IOUtils.toByteArray(fis));
        IOUtils.closeQuietly(fis);
//        System.out.println("MD5:" + md5);
        return md5;
    }
    /**
     * 从ftp服务器获取文件MD5
     * @param
     *@throws Exception
     **/
//    public String MD5ZipFile(String remoteDir, String wantFileName, String ipAddr, String user, String pass) throws Exception {
//
//        //输出信息字符串
//        String str;
//        //和服务器建立连接
//        FtpClient ftp = FtpClient.create(ipAddr); // 根据服务器ip建立连接
//
//        //获得响应信息
//        str = ftp.getLastResponseString();
//        logger.info("连接服务器:" + str);
//
//        //登陆到Ftp服务器// 根据用户名和密码登录服务器
//        ftp.login(user, pass.toCharArray());
//
//        str = ftp.getLastResponseString();
//        logger.info("登录:" + str);
//
//        //打开并定位到服务器目录
//        //打开服务器上的文件目录
//        str = ftp.getLastResponseString();
//        logger.info("打开服务器目录:" + str);
//        // 转化为二进制的文件
//        ftp.setBinaryType();
//        // 找到要读取的文件
//
//        //TelnetInputStream ftpIn = ftp.get(wantFileName + ".zip");
//        //TelnetInputStream ftpIn = ftp.getFileStream(wantFileName + ".zip");
//        InputStream ftpIn = ftp.getFileStream(remoteDir + wantFileName);
//
//        FileInputStream fis = (FileInputStream)ftpIn;
//        String md5 = DigestUtils.md5Hex(IOUtils.toByteArray(fis));
//        IOUtils.closeQuietly(fis);
//        //System.out.println("MD5:"+md5);
//        return md5;
//
//    }

    /**
     * 从ftp服务器自动扫描下载文件
     *
     * @param
     * @throws Exception
     **/
    public void timeLoadZipFile(String remoteDir, String localDir, String wantFileName, String ipAddr, String user, String pass) throws Exception {

        //输出信息字符串
        String str;
        //和服务器建立连接
        FtpClient ftp = FtpClient.create(ipAddr); // 根据服务器ip建立连接

        //获得响应信息
        str = ftp.getLastResponseString();
        logger.info("连接服务器:" + str);

        //登陆到Ftp服务器// 根据用户名和密码登录服务器
        ftp.login(user, pass.toCharArray());

        if (!getServerFileNameList(ftp, remoteDir, wantFileName)) {
            SunFtpUtil.getSunFtpUtil().timeLoadZipFile(remoteDir, localDir, wantFileName, ipAddr, user, pass);
        } else {

        }

        str = ftp.getLastResponseString();
        logger.info("登录:" + str);

        //打开并定位到服务器目录
        //打开服务器上的文件目录
        str = ftp.getLastResponseString();
        logger.info("打开服务器目录:" + str);
        // 转化为二进制的文件
        ftp.setBinaryType();
        // 找到要读取的文件

        //TelnetInputStream ftpIn = ftp.get(wantFileName + ".zip");
        //TelnetInputStream ftpIn = ftp.getFileStream(wantFileName + ".zip");
        InputStream ftpIn = ftp.getFileStream(remoteDir + wantFileName);
        //TelnetInputStream ftpIn = new TelnetInputStream(xInputStream);

        byte[] buf = new byte[204800];
        int bufsize = 0;
        //File f = new File("c:\\BaseMap");

        String toLocalPath = localDir + wantFileName;
       /*File f=new File(toLocalPath);
       f.mkdirs();*/
        FileOutputStream ftpOut = new FileOutputStream(toLocalPath);
        int readLine = 0;
        while ((bufsize = ftpIn.read(buf, 0, buf.length)) != -1) {
            //System.out.println(bufsize);
            ftpOut.write(buf, 0, bufsize);
            readLine = +bufsize;
        }
        System.out.println(readLine);
        ftpOut.close();
        ftpIn.close();
        ftp.close();
        logger.info("下载" + wantFileName + ",完成!");

    }
}

